package com.huajx.tuopuda.client.udp;

import com.huajx.util.BitUtil;
import com.huajx.util.ByteUtil;
import com.huajx.util.HexUtil;
import com.huajx.util.date.DateUtil;

import java.util.Calendar;
import java.util.Date;

/**
 * @program: di-parent
 * @description:
 * @author: lisa 叶新华
 * @create: 2019-09-24 13:17
 */
public class TuopudaUtil {


    /**
     * 10位卡号转8位卡号
     * <p>
     * 8位卡号：wiegand26国际标准的卡号输出方式
     * 10位卡号：采用直接读卡号的内码的方式做卡号
     * <p>
     * 首先10位数转换为16进制是4个字节，
     * 第一个字节不要，
     * 第二个字节转换为8位卡号的前3位，
     * 第三个和第四个字节一起转换位8位卡号的后5位数
     *
     * @param cardId 10位卡号
     * @return 8位卡号
     */
    public static long toCardId8BitFrom10Bit(String cardId) {
        long id = Long.valueOf(cardId);
        return (id & 0xFFFF) + (id >> 16 & 0xFF) * 100000;
    }

    /**
     * 解析拓扑达协议中日期数据
     * <p>
     * Year(年):                 前7位                0–119(relative to 2000)
     * Month(月):                中间4位：8-11位       1–12
     * Day(日):                  后5位                1–31
     * <p>
     * Hours(时)：                前5位               0–23
     * Minutes(分)：              中间6位： 6-11位     0–59
     * 2-second increments(2秒)： 后5位               0-29 in 2-second intervals
     *
     * @param bytes 4位byte数组
     * @return 日期
     */
    public static Date bytesToDate(byte[] bytes) {
        int ymd = ByteUtil.bytesToShort(new byte[]{bytes[0], bytes[1]});
        int hms = ByteUtil.bytesToShort(new byte[]{bytes[2], bytes[3]});

        int year = BitUtil.splitByStart(ymd, 7);
        int month = BitUtil.split(ymd, 7, 4);
        int day = BitUtil.splitByEnd(ymd, 5);

        int hour = BitUtil.splitByStart(hms, 5);
        int minute = BitUtil.split(hms, 5, 6);
        int second = BitUtil.splitByEnd(hms, 5);

        Calendar calendar = Calendar.getInstance();
        calendar.set(year + 2000, month - 1, day, hour, minute, second * 2);
        return calendar.getTime();
    }

    /**
     * 日期转为字节数组
     *
     * @param date
     * @param hasTime
     * @return
     */
    public static byte[] dateToBytes(Date date, boolean hasTime) {
        int ymd = dateToDateInt(date);

        if(hasTime){
            int hms = dateToTimeInt(date);
            return ByteUtil.bytesByLength(ymd << 16 | hms, 4);
        } else {
            return ByteUtil.bytesByLength(ymd, 2);
        }
    }

    public static int dateToDateInt(Date date) {
        int year = DateUtil.year(date) - 2000;
        int month = DateUtil.month(date) + 1;
        int day = DateUtil.dayOfMonth(date);

        return year << 9 | month <<  5 | day;
    }

    public static int dateToTimeInt(Date date) {
        int hour = DateUtil.hour(date, true);
        int minute = DateUtil.minute(date);
        int second = DateUtil.second(date);

        return hour << 11 | minute << 5 |second;
    }

//    /**
//     * 根据SN获取Hex字符串
//     * <p>
//     * 转为二位字节
//     *
//     * @param sn
//     * @return
//     */
//    public static String toSnHex(int sn) {
//        return BitUtil.to2ByteHexByShort((short) sn);
//    }

    /**
     * 替换字节数组，从指定位置开始，到相应位置结束
     *
     * @param bytes 待替换数组
     * @param value 替换值 转换为16进制
     * @param start 开始位置
     * @param len   替换长度
     *
     * @return  替换值的较验和
     */
    public static int replaceBytes(byte[] bytes, int value, int start, int len) {
        int sum = 0;
        byte[] vbs = ByteUtil.bytesByLength(value, len);
        for (int i = 0; i < len; i++) {
            bytes[start + i] = vbs[i];
            int mNum = (vbs[i] >= 0) ? vbs[i] : (vbs[i] + 256); // 较验和

            sum += mNum;
        }
        return sum;
    }
    
    /**
     * 替换字节数组，从指定位置开始，到相应位置结束
     *
     * @param bytes 待替换数组
     * @param value 替换值
     * @param start 开始位置
     * @param len   替换长度
     *
     * @return  替换值的较验和
     */
    public static int replaceBytes(byte[] bytes, byte[] vbs, int start, int len) {
        int sum = 0;
       // byte[] vbs = ByteUtil.bytesByLength(value, len);
        for (int i = 0; i < len; i++) {
            bytes[start + i] = vbs[i];
            int mNum = (vbs[i] >= 0) ? vbs[i] : (vbs[i] + 256); // 较验和

            sum += mNum;
        }
        return sum;
    }

    /**
     * 求余
     *
     * @param d         数值
     * @param remainder 余商
     * @return
     */
    public static int toRemainder(int d, int remainder) {
        return d & (remainder - 1);
    }

    public static void main(String[] args) {
//        byte[] bytes = new byte[]{(byte)0X7E,
//                (byte)0X00, (byte)0X95,
//                (byte)0X81, (byte)0X10};
//        byte[] reverse = ArrayUtil.reverse(bytes); // 反转数组
        System.out.println(toCardId8BitFrom10Bit("1240420310"));
        System.out.println(toCardId8BitFrom10Bit("0013961168"));
        System.out.println(toCardId8BitFrom10Bit("2681949746"));
        System.out.println(toCardId8BitFrom10Bit("1145397494"));
        System.out.println(toCardId8BitFrom10Bit("0185141580"));

//        System.out.println("38144 --> " + toSnHex(38144));
//        System.out.println("38203 --> " + toSnHex(38203));
//        System.out.println("38203 --> " + toSnHex(38203));

//        System.out.println("1081-->" + BitUtil.to2ByteHexByShort((short) TuopudaDirect.D_1081));
//        System.out.println("108D-->" + BitUtil.to2ByteHexByShort((short) TuopudaDirect.D_108d));

//        toMessage(38144, TuopudaDirect.D_1081, 1);
    }
}
